package com.wfy.modules.sys.service.impl;

import com.wfy.common.config.Global;
import com.wfy.common.security.Digests;
import com.wfy.common.security.shiro.utils.ShiroHolder;
import com.wfy.common.service.CrudService;
import com.wfy.common.service.ServiceException;
import com.wfy.common.util.CacheUtils;
import com.wfy.common.util.StringUtils;
import com.wfy.modules.sys.dao.MenuDao;
import com.wfy.modules.sys.dao.RoleDao;
import com.wfy.modules.sys.dao.UserDao;
import com.wfy.modules.sys.dto.UserDto;
import com.wfy.modules.sys.entity.Menu;
import com.wfy.modules.sys.entity.Role;
import com.wfy.modules.sys.entity.User;
import com.wfy.modules.sys.service.IUserService;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.Date;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

/**
 * Created with IntelliJ IDEA.
 *
 * @author: wangxindong
 * @date: 2018/5/19-11:13
 */
@Service
@Transactional(readOnly = true, rollbackFor = Exception.class)
public class UserServiceImpl extends CrudService<UserDao, User> implements IUserService<User> {

    // ================================================================
    // Constants
    // ================================================================

    // ================================================================
    // Fields
    // ================================================================

    @Resource
    private MenuDao menuDao;

    @Resource
    private RoleDao roleDao;

    @Resource
    private RedisTemplate redisTemplate;


    // ================================================================
    // Constructors
    // ================================================================

    // ================================================================
    // Methods from/for super Interfaces or SuperClass
    // ================================================================

    @Override
    public User getUserByLoginName(String loginName) {
        User user = baseMapper.getByLoginName(loginName);
        return user;
    }

    @Override
    public User getUserInfo(String id) {
        User user = (User) CacheUtils.get(id);
        if (user != null) {
            return user;
        }

        user = baseMapper.getUserInfo(id);
        if (null == user) {
            throw new ServiceException(Global.INVALID_PARAMS_CODE, Global.INVALID_PARAMS_MSG);
        }

        Menu menu = new Menu();
        menu.setUserId(user.getId());
        /**
         * 菜单权限
         */
        List<Menu> menus = menuDao.findByUserId(menu);
        if (null != menus && !menus.isEmpty()) {
            Set<String> permissions = new HashSet<>(menus.size());
            for (Menu m : menus) {
                permissions.add(m.getPermission());
            }
            user.setPermissions(permissions);
        }

        // 角色数据
        Role role = new Role();
        role.setUserId(user.getId());
        List<Role> roles = roleDao.getByUserId(user.getId());
        if (null != roles && !roles.isEmpty()) {
            user.setRoleList(roles);
        }

        CacheUtils.put(user.getId(), user);
        return user;
    }

    /**
     * 创建用户
     *
     * @param userDto
     * @return
     */
    @Transactional(readOnly = false, rollbackFor = Exception.class)
    @Override
    public User createUser(UserDto userDto) {
        String password = userDto.getPassword();
        String againPassword = userDto.getAgainPassword();
        if (StringUtils.isEmpty(password) || StringUtils.isEmpty(againPassword) ||
                !password.equals(againPassword)) {
            throw new ServiceException(Global.DEFAULT_VALIDATOR_CODE, Global.DEFAULT_VALIDATOR_MSG);
        }

        User u = userDto.build();
        User tmp = baseMapper.getByLoginName(userDto.getLoginName());
        if (null != tmp) {
            throw new ServiceException(Global.USER_EXIST_CODE, Global.USER_EXIST_MSG);
        }

        u.setPassword(Digests.entryptPassword(password));

        u.setCreateDate(new Date());
        u.setUpdateDate(new Date());
        u.setCreateBy(ShiroHolder.getUser().getId());
        u.setUpdateBy(ShiroHolder.getUser().getId());

        // 创建用户
        baseMapper.insert(u);

        // 增加权限
        // TODO

        return u;
    }

    // ================================================================
    // Public or Protected Methods
    // ================================================================


    // ================================================================
    // Getter & Setter
    // ================================================================

    // ================================================================
    // Private Methods
    // ================================================================


    // ================================================================
    // Inner or Anonymous Class
    // ================================================================

    // ================================================================
    // Test Methods
    // ================================================================

}
